bitkeeper revision 1.1159.1.168 (4152d33dmJ9oXFP7VWvfCRpxNf8e6g)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 23 Sep 2004 13:44:29 +0000 (13:44 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Thu, 23 Sep 2004 13:44:29 +0000 (13:44 +0000)
Merge xenbk@gandalf:/var/bk/xeno-unstable.bk
into wray-m-3.hpl.hp.com:/home/mjw/repos-bk/xeno-unstable.bk

1  2 
linux-2.6.8.1-xen-sparse/drivers/xen/netfront/netfront.c

index bc3d2363263041cbdf0329e713c1503731f188f1,485d23b8d18d980a239f4cb8f9957ff5da734cb6..a579a784e864b6ecf627048226db9f90c4d96276
@@@ -714,134 -705,159 +755,159 @@@ static void network_connect(struct net_
      if ( np->user_state == UST_OPEN )
          netif_start_queue(dev);
  
 -    spin_unlock(&np->tx_lock);
 -    spin_unlock_irq(&np->rx_lock);
 +    spin_unlock(&np->rx_lock);
 +    spin_unlock_irq(&np->tx_lock);
  }
  
- static void netif_status_change(netif_fe_interface_status_changed_t *status)
- {
-     ctrl_msg_t                   cmsg;
-     netif_fe_interface_connect_t up;
-     struct net_device *dev;
-     struct net_private *np;
-     
-     DPRINTK(">\n");
-     DPRINTK("> status=%d handle=%d mac=%02x:%02x:%02x:%02x:%02x:%02x\n",
-            status->status,
-            status->handle,
-            status->mac[0], status->mac[1], status->mac[2],
-            status->mac[3], status->mac[4], status->mac[5]);
-     if ( netctrl.interface_n <= 0 )
-     {
-         printk(KERN_WARNING "Status change: no interfaces\n");
-         return;
+ static void vif_show(struct net_private *np){
+ #if DEBUG
+     if(np){
+         IPRINTK(" <vif handle=%u %s(%s) evtchn=%u irq=%u tx=%p rx=%p>\n",
+                np->handle,
+                be_state_name[np->backend_state],
+                user_state_name[np->user_state],
+                np->evtchn,
+                np->irq,
+                np->tx,
+                np->rx);
+     } else {
+         IPRINTK("<vif NULL>\n");
      }
+ #endif
+ }
  
-     dev = find_dev_by_handle(status->handle);
-     if(!dev){
-         printk(KERN_WARNING "Status change: invalid netif handle %u\n",
-                status->handle);
-          return;
-     }
-     np  = dev->priv;
-     
-     switch ( status->status )
-     {
-     case NETIF_INTERFACE_STATUS_DESTROYED:
-         printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n",
-                np->backend_state);
-         break;
+ /* Send a connect message to xend to tell it to bring up the interface.
+  */
+ static void send_interface_connect(struct net_private *np){
+     ctrl_msg_t cmsg = {
+         .type    = CMSG_NETIF_FE,
+         .subtype = CMSG_NETIF_FE_INTERFACE_CONNECT,
+         .length  = sizeof(netif_fe_interface_connect_t),
+     };
+     netif_fe_interface_connect_t *msg = (void*)cmsg.msg;
+     DPRINTK(">\n"); vif_show(np); 
+     msg->handle = np->handle;
+     msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT);
+     msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT);
+         
+     ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
+     DPRINTK("<\n");
+ }
  
-     case NETIF_INTERFACE_STATUS_DISCONNECTED:
-         if ( np->backend_state != BEST_CLOSED )
-         {
-             printk(KERN_WARNING "Unexpected netif-DISCONNECTED message"
-                    " in state %d\n", np->backend_state);
-           printk(KERN_INFO "Attempting to reconnect network interface\n");
-             /* Begin interface recovery.
-            *
-            * NB. Whilst we're recovering, we turn the carrier state off.  We
-            * take measures to ensure that this device isn't used for
-            * anything.  We also stop the queue for this device.  Various
-            * different approaches (e.g. continuing to buffer packets) have
-            * been tested but don't appear to improve the overall impact on
-              * TCP connections.
-            *
-              * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
-              * is initiated by a special "RESET" message - disconnect could
-              * just mean we're not allowed to use this interface any more.
-              */
-             /* Stop old i/f to prevent errors whilst we rebuild the state. */
-             spin_lock_irq(&np->tx_lock);
-             spin_lock(&np->rx_lock);
-             netif_stop_queue(dev);
-             np->backend_state = BEST_DISCONNECTED;
-             spin_unlock(&np->rx_lock);
-             spin_unlock_irq(&np->tx_lock);
-             /* Free resources. */
-             free_irq(np->irq, dev);
-             unbind_evtchn_from_irq(np->evtchn);
-           free_page((unsigned long)np->tx);
-             free_page((unsigned long)np->rx);
-         }
+ /* Send a driver status notification to the domain controller. */
+ static int send_driver_status(int ok)
+ {
+     int err = 0;
+     ctrl_msg_t cmsg = {
+         .type    = CMSG_NETIF_FE,
+         .subtype = CMSG_NETIF_FE_DRIVER_STATUS,
+         .length  = sizeof(netif_fe_driver_status_t),
+     };
+     netif_fe_driver_status_t *msg = (void*)cmsg.msg;
+     msg->status = (ok ? NETIF_DRIVER_STATUS_UP : NETIF_DRIVER_STATUS_DOWN);
+     err = ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
+     return err;
+ }
  
-         /* Move from CLOSED to DISCONNECTED state. */
-         np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
-         np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
-         memset(np->tx, 0, PAGE_SIZE);
-         memset(np->rx, 0, PAGE_SIZE);
-         np->backend_state = BEST_DISCONNECTED;
-         /* Construct an interface-CONNECT message for the domain controller. */
-         cmsg.type      = CMSG_NETIF_FE;
-         cmsg.subtype   = CMSG_NETIF_FE_INTERFACE_CONNECT;
-         cmsg.length    = sizeof(netif_fe_interface_connect_t);
-         up.handle      = status->handle;
-         up.tx_shmem_frame = virt_to_machine(np->tx) >> PAGE_SHIFT;
-         up.rx_shmem_frame = virt_to_machine(np->rx) >> PAGE_SHIFT;
-         memcpy(cmsg.msg, &up, sizeof(up));
-         
-         /* Tell the controller to bring up the interface. */
-         ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
-         break;
+ /* Stop network device and free tx/rx queues and irq.
+  */
+ static void vif_release(struct net_private *np){
  
-     case NETIF_INTERFACE_STATUS_CONNECTED:
-         if ( np->backend_state == BEST_CLOSED )
-         {
-             printk(KERN_WARNING "Unexpected netif-CONNECTED message"
-                    " in state %d\n", np->backend_state);
-             break;
-         }
+     /* Stop old i/f to prevent errors whilst we rebuild the state. */
+     spin_lock_irq(&np->tx_lock);
+     spin_lock(&np->rx_lock);
+     netif_stop_queue(np->dev);
+     //np->backend_state = BEST_DISCONNECTED;
+     spin_unlock(&np->rx_lock);
+     spin_unlock_irq(&np->tx_lock);
+     
+     /* Free resources. */
+     if(np->tx != NULL){
+         free_irq(np->irq, np->dev);
+         unbind_evtchn_from_irq(np->evtchn);
+         free_page((unsigned long)np->tx);
+         free_page((unsigned long)np->rx);
+         np->irq = 0;
+         np->evtchn = 0;
+         np->tx = NULL;
+         np->rx = NULL;
+     }
  
-         memcpy(dev->dev_addr, status->mac, ETH_ALEN);
+ }
  
-         network_connect(dev, status);
+ /* Release vif resources and close it down completely.
+  */
+ static void vif_close(struct net_private *np){
+     DPRINTK(">\n"); vif_show(np);
+     WPRINTK(" Unexpected netif-CLOSED message in state %s\n",
+             be_state_name[np->backend_state]);
+     vif_release(np);
+     np->backend_state = BEST_CLOSED;
+     //todo: take dev down and free.
+     vif_show(np); DPRINTK("<\n");
+ }
  
-         np->evtchn = status->evtchn;
-         np->irq = bind_evtchn_to_irq(np->evtchn);
-         (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, 
-                           dev->name, dev);
-         netctrl_connected_count();
-         vif_wake(dev);
-         break;
+ /* Move the vif into disconnected state.
+  * Allocates tx/rx pages.
+  * Sends connect message to xend.
+  */
+ static void vif_disconnect(struct net_private *np){
+     DPRINTK(">\n");
+     if(np->tx) free_page((unsigned long)np->tx);
+     if(np->rx) free_page((unsigned long)np->rx);
+     // Before this np->tx and np->rx had better be null.
+     np->tx = (netif_tx_interface_t *)__get_free_page(GFP_KERNEL);
+     np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
+     memset(np->tx, 0, PAGE_SIZE);
+     memset(np->rx, 0, PAGE_SIZE);
+     np->backend_state = BEST_DISCONNECTED;
+     send_interface_connect(np);
+     vif_show(np); DPRINTK("<\n");
+ }
  
-     case NETIF_INTERFACE_STATUS_CHANGED:
-         /* The domain controller is notifying us that a device has been
-         * added or removed.
-         */
-         break;
+ /* Begin interface recovery.
+  *
+  * NB. Whilst we're recovering, we turn the carrier state off.  We
+  * take measures to ensure that this device isn't used for
+  * anything.  We also stop the queue for this device.  Various
+  * different approaches (e.g. continuing to buffer packets) have
+  * been tested but don't appear to improve the overall impact on
+  * TCP connections.
+  *
+  * TODO: (MAW) Change the Xend<->Guest protocol so that a recovery
+  * is initiated by a special "RESET" message - disconnect could
+  * just mean we're not allowed to use this interface any more.
+  */
+ static void vif_reset(struct net_private *np){
+     DPRINTK(">\n");
+     IPRINTK(" Attempting to reconnect network interface: handle=%u\n",
+             np->handle);
+     
+     vif_release(np);
+     vif_disconnect(np);
+     vif_show(np); DPRINTK("<\n");
+ }
  
-     default:
-         printk(KERN_WARNING "Status change to unknown value %d\n", 
-                status->status);
-         break;
-     }
+ /* Move the vif into connected state.
+  * Sets the mac and event channel from the message.
+  * Binds the irq to the event channel.
+  */
+ static void vif_connect(struct net_private *np, netif_fe_interface_status_t *status){
+     struct net_device *dev = np->dev;
+     DPRINTK(">\n");
+     memcpy(dev->dev_addr, status->mac, ETH_ALEN);
+     network_connect(dev, status);
+     np->evtchn = status->evtchn;
+     np->irq = bind_evtchn_to_irq(np->evtchn);
+     (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev);
+     netctrl_connected_count();
+     vif_wake(dev);
+     vif_show(np); DPRINTK("<\n");
  }
  
  /** Create a network device.
   * @param handle device handle
   * @param val return parameter for created device